package com.warrior.superdata.dds.datasource;

import com.warrior.superdata.constants.ActionConstants;
import com.warrior.superdata.dds.domain.DBVo;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;

/**
 * 创建动态数据源
 */
@Slf4j
public class DynamicDataSource extends HikariDataSource {
    /**
     * 创建数据库连接
     *
     * @return
     */
    @Override
    public Connection getConnection() {
        Connection result = null;
        // 获取数据库标识
        String projectCode = DBIdentifier.getProjectCode();
        // 按照数据库标识获取数据源信息
        HikariDataSource dds = DDSHolder.instance().getDDS(projectCode);
        if (dds == null) {
            try {
                dds = initDDS(projectCode);
                DDSHolder.instance().addDDS(projectCode, dds);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                log.error("Init data source fail. projectCode:" + projectCode);
            }
        }
        try {
            result = dds.getConnection();
        } catch (SQLException e) {
            log.error("create connection fail. ex: {}", e.getMessage());
        } finally {
            DDSHolder.instance().checkIdelDataSource();
        }
        return result;
    }

    /**
     * 初始化数据源
     *
     * @param projectCode
     * @return
     */
    private HikariDataSource initDDS(String projectCode) throws IllegalAccessException {
        HikariConfig hikariConfig = new HikariConfig();
        DBVo dbVo = ProjectDBMgr.instance().getDBInfo(projectCode);
        if (Objects.isNull(dbVo)) {
            return null;
        }
        // 设置数据库连接信息
        String urlFormat = ActionConstants.MYSQL_URL_PREFIX;
        //拼接url
        String url = String.format(urlFormat + "%s%s%s?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true",
                dbVo.getIp() + ":", dbVo.getPort() + "/", StringUtils.isEmpty(dbVo.getDbname()) ? "" : dbVo.getDbname());
        if (ActionConstants.HIVE_TYPE.equals(dbVo.getDbType())) {
            urlFormat = ActionConstants.HIVE_URL_PREFIX;
            url = String.format(urlFormat + "%s%s", dbVo.getIp() + ":", dbVo.getPort());
            hikariConfig.setDriverClassName(ActionConstants.HIVE_DRIVER);
            hikariConfig.setConnectionTestQuery("SELECT 1");
        }
        if (ActionConstants.ORACLE_TYPE.equals(dbVo.getDbType())) {
            urlFormat = ActionConstants.ORACLE_URL_PREFIX;
            url = String.format(urlFormat + "%s%s" + "/orcl", dbVo.getIp() + ":", dbVo.getPort());
            hikariConfig.setDriverClassName(ActionConstants.ORACLE_DRIVER);
        }
        hikariConfig.setJdbcUrl(url);
        hikariConfig.setUsername(dbVo.getUsername());
        hikariConfig.setPassword(dbVo.getPassword());
        hikariConfig.setMinimumIdle(5);
        hikariConfig.setMaximumPoolSize(20);
        hikariConfig.setIdleTimeout(10000);
        // 30秒超时
        hikariConfig.setConnectionTimeout(30000);
        HikariDataSource dds = new HikariDataSource(hikariConfig);
        return dds;
    }

}
